home *** CD-ROM | disk | FTP | other *** search
Lex Description | 1995-08-14 | 8.5 KB | 383 lines |
- %{
- #include "global.h"
-
- #define CMB_UMINUS ('-' | 0x80)
- #define CMB_UNEG ('!' | 0x80)
-
- extern unsigned long tmp_labels[10][2], tmp_label_cnt;
- extern char *msprintf P_((const char *, ...));
- extern struct numstr combine P_((struct numstr, struct numstr, int));
- %}
-
- %union {
- long num;
- char *str;
- struct numstr numstr;
- }
-
- %token NL
- %token <str> OP OP_MREG ID STRING REG TMPLABEL TMPLABELfb
- %token <str> D_COMM D_LCOMM D_ELIST D_IDLIST D_NONE D_OPTINT D_ORG
- %token <str> D_SLIST D_UNS
- %token <num> NUMBER
-
- %type <str> operand reglist regrange expr sym_expr size_field
- %type <str> expr_list id_list string_list
- %type <num> op
- %type <numstr> num_val
-
- %left '+' '-'
- %left '&' '^' '!' '|'
- %left '*' '/' '%' '>' '<'
- %left UMINUS
-
- %%
-
- prog: linelist;
-
- linelist: /* nothing */
- | linelist line {fputc('\n', yyout);}
- ;
-
- line: label directives NL
- | label instr NL
- | label NL
- | macro NL
- ;
-
- label: /* nothing */
- | ID ':' {
- fprintf(yyout, "%s:", $1);
- if (strlen($1) > 6) fputc('\n', yyout);
- free($1);
- }
- | TMPLABEL {
- int i = $1[0] - '0';
- if (tmp_labels[i][1] == 0)
- tmp_labels[i][0] = ++tmp_label_cnt;
- else
- tmp_labels[i][0] = tmp_labels[i][1];
- tmp_labels[i][1] = 0;
- fprintf(yyout, "LT%lu:", tmp_labels[i][0]);
- }
- ;
-
- directives: directive
- | directives ';' {fputc('\n', yyout);} directive
- ;
-
- directive: D_COMM ID ',' num_val {
- fprintf(yyout, "\t%s\t%s, %ld", $1, $2, $4.num);
- free($1); free($2); free($4.str);
- }
- | D_LCOMM ID ',' num_val {
- fprintf(yyout, "%s:%s\t%s\t%ld", $2,
- (strlen($2) <= 6 ? "" : "\n"), $1, $4.num
- );
- free($1); free($2); free($4.str);
- }
- | D_ELIST expr_list {
- fprintf(yyout, "\t%s\t%s", $1, $2); free($1); free($2);
- }
- | D_IDLIST id_list {
- fprintf(yyout, "\t%s\t%s", $1, $2); free($1); free($2);
- }
- | D_NONE {
- fprintf(yyout, "\t%s", $1); free($1);
- }
- | D_OPTINT {
- fprintf(yyout, "\t%s", $1); free($1);
- }
- | D_OPTINT num_val {
- fprintf(yyout, "\t%s", $1); free($1); free($2.str);
- }
- | D_ORG expr {
- fprintf(yyout, "\t%s\t%s", $1, $2); free($1); free($2);
- }
- | D_SLIST string_list {
- fprintf(yyout, "\t%s\t%s", $1, $2); free($1); free($2);
- }
- | D_UNS {yyerror("warning: unsupported assembler directive %s", $1);}
- ;
-
- instr: OP {fprintf(yyout, "\t%s", $1);}
- | OP operand {
- fprintf(yyout, "\t%s\t%s", $1, $2); free($1); free($2);
- }
- | OP operand ',' operand {
- fprintf(yyout, "\t%s\t%s, %s", $1, $2, $4);
- free($1); free($2); free($4);
- }
- | OP_MREG reglist ',' operand {
- fprintf(yyout, "\t%s\t%s, %s", $1, $2, $4);
- free($1); free($2); free($4);
- }
- | OP_MREG operand ',' reglist {
- fprintf(yyout, "\t%s\t%s, %s", $1, $2, $4);
- free($1); free($2); free($4);
- }
- ;
-
- operand: '#' expr {$$ = msprintf("#%s", $2); free($2);}
- | REG {$$ = $1;}
- | REG '@' {$$ = msprintf("(%s)", $1); free($1);}
- | REG '@' '+' {$$ = msprintf("(%s)+", $1); free($1);}
- | REG '@' '-' {$$ = msprintf("-(%s)", $1); free($1);}
- | REG '@' '(' expr ')' {
- $$ = msprintf("%s(%s)", $4, $1);
- free($1); free($4);
- }
- | REG '@' '(' expr ',' REG size_field ')' {
- $$ = msprintf("%s(%s,%s%s)", $4, $1, $6, $7);
- free($1); free($4); free($6); free($7);
- }
- | expr {$$ = $1;}
- ;
-
- macro: ID '=' expr {
- fprintf(yyout, "%s\t=\t%s", $1, $3);
- free($1); free($3);
- }
- ;
-
- size_field: /* nothing */ {$$[0] = '\0';}
- | ':' ID {$$ = msprintf(".%s", $2); free($2);}
- ;
-
- reglist: regrange {$$ = $1;}
- | REG '/' REG {$$ = msprintf("%s/%s", $1, $3); free($1); free($3);}
- | REG '/' regrange {
- $$ = msprintf("%s/%s", $1, $3);
- free($1); free($3);
- }
- | reglist '/' REG {
- $$ = msprintf("%s/%s", $1, $3);
- free($1); free($3);
- }
- | reglist '/' regrange {
- $$ = msprintf("%s/%s", $1, $3);
- free($1); free($3);
- }
- ;
-
- regrange: REG '-' REG {
- $$ = msprintf("%s-%s", $1, $3);
- free($1); free($3);
- }
- ;
-
- expr: num_val {$$ = msprintf("%ld", $1); free($1.str);}
- | sym_expr {$$ = $1;}
- ;
-
- sym_expr: ID {$$ = $1;}
- | TMPLABELfb {
- int i = $1[0] - '0';
- unsigned long l;
- if ($1[1] == 'f') {
- if (tmp_labels[i][1] == 0)
- tmp_labels[i][1] = ++tmp_label_cnt;
- l = tmp_labels[i][1];
- } else {
- l = tmp_labels[i][0];
- if (l == 0)
- yyerror("Unresolved temporary label %db", i);
- }
- $$ = msprintf("LT%lu", l); free($1);
- }
- | sym_expr op sym_expr {
- $$ = msprintf("%s%c%s", $1, (char)$2, $3);
- free($1); free($3);
- }
- | num_val op sym_expr {
- $$ = msprintf("%s%c%s", $1.str, (char)$2, $3);
- free($1.str); free($3);
- }
- | sym_expr op num_val {
- $$ = msprintf("%s%c%s", $1, (char)$2, $3.str);
- free($1); free($3.str);
- }
- ;
-
- op: '+' {$$ = '+';}
- | '-' {$$ = '-';}
- | '&' {$$ = '&';}
- | '^' {$$ = '^';}
- | '|' {$$ = '|';}
- | '*' {$$ = '&';}
- | '/' {$$ = '/';}
- | '%' {$$ = '%';}
- | '<' {$$ = '<';}
- | '>' {$$ = '>';}
- ;
-
- num_val: NUMBER {$$.num = $1; $$.str = msprintf("%ld", $1);}
- | num_val op num_val {$$ = combine($1, $3, (int)$2);}
- | '-' num_val %prec UMINUS {$$ = combine($2, $2, CMB_UMINUS);}
- | '!' num_val %prec UMINUS {$$ = combine($2, $2, CMB_UNEG);}
- | '(' num_val ')' {$$ = $2;}
- ;
-
- expr_list: expr {$$ = $1;}
- | expr_list ',' expr {
- $$ = msprintf("%s, %s", $1, $3);
- free($1); free($3);
- }
- ;
-
- id_list: ID {$$ = $1;}
- | id_list ',' ID {
- $$ = msprintf("%s, %s", $1, $3);
- free($1); free($3);
- }
- ;
-
- string_list: STRING {$$ = $1;}
- | string_list ',' STRING {
- $$ = msprintf("%s, %s", $1, $3);
- free($1); free($3);
- }
- ;
-
- %%
-
- #include <stdarg.h>
- #include <string.h>
- #include <time.h>
- #include <unistd.h>
- #include "global.h"
- #include "patchlev.h"
-
- #ifdef __MINT__
- long _stksize = 65536L;
- #endif
-
- unsigned long tmp_labels[10][2];
- unsigned long tmp_label_cnt;
-
- #ifdef __STDC__
- char *msprintf(const char *fmt, ...)
- #else
- char *msprintf(fmt)
- const char *fmt;
- #endif
- {
- va_list ap;
- static char buf[256];
-
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- va_end(ap);
- return strdup(buf);
- }
-
- struct numstr combine(n1, n2, op)
- struct numstr n1, n2;
- int op;
- {
- struct numstr n0;
-
- if (op & 0x80) {
- n0.str = msprintf("%c%s", (op ^ 0x80), n1.str);
- free(n1.str);
- } else {
- n0.str = msprintf("%s%c%s", n1.str, op, n2.str);
- free(n1.str); free(n2.str);
- }
-
- switch (op) {
- case '+': n0.num = n1.num + n2.num; break;
- case '-': n0.num = n1.num - n2.num; break;
- case '&': n0.num = n1.num & n2.num; break;
- case '^': n0.num = n1.num ^ n2.num; break;
- case CMB_UNEG: n0.num = !n1.num; break;
- case '|': n0.num = n1.num | n2.num; break;
- case '*': n0.num = n1.num & n2.num; break;
- case '/': n0.num = n1.num / n2.num; break;
- case '%': n0.num = n1.num % n2.num; break;
- case '<': n0.num = n1.num << n2.num; break;
- case '>': n0.num = n1.num >> n2.num; break;
- case CMB_UMINUS: n0.num = -n1.num; break;
- }
-
- return n0;
- }
-
- main(ac, av)
- int ac;
- char *av[];
- {
- char *s, buf[40], outfnam[40];
- int i;
- time_t t;
- struct tm *T;
-
- #if YYDEBUG != 0
- yydebug = 1;
- #endif
- if ((ac != 2) && (ac != 4)) {
- fprintf(stderr, "usage: %s [-o filename] filename\n", av[0]);
- exit(1);
- }
- if (!(yyin = fopen(av[ac - 1], "r"))) {
- fprintf(stderr, "%s: cannot open input file %s\n", av[0], av[ac - 1]);
- exit(1);
- }
- if (ac == 4) {
- strcpy(outfnam, av[2]);
- } else {
- strcpy(outfnam, av[ac - 1]);
- s = strrchr(outfnam, '.');
- if (!s)
- strcat(outfnam, ".s");
- else
- strcpy(s + 1, "s");
- }
- if (!(yyout = fopen(outfnam, "w"))) {
- fprintf(stderr, "%s: cannot open output file %s\n", av[0], outfnam);
- exit(1);
- }
- time(&t);
- T = localtime(&t);
- strftime(buf, 40, "%b %d %Y %H:%M:%S", T);
- fprintf(yyout, "; Generated by mit2mot v%d.%d.%d on %s\n\n",
- M2M_VERSION, M2M_RELEASE, M2M_PATCHLEVEL, buf);
- init_hash();
- if (yyparse() != 0) {
- clear_hash();
- fclose(yyin);
- fclose(yyout);
- unlink(outfnam);
- exit(1);
- }
- for (i = 0; i < 10; i++)
- if (tmp_labels[i][1] != 0) {
- yyerror("Unresolved temporary label %df", i);
- fprintf(yyout, "LT%lu:\n", tmp_labels[i][1]);
- }
- clear_hash();
- fclose(yyin);
- fclose(yyout);
- return 0;
- }
-
- #ifdef __STDC__
- void yyerror(const char *s, ...)
- #else
- void yyerror(s)
- const char *s;
- #endif
- {
- va_list ap;
-
- fprintf(stderr, "At line %lu: ", line_num);
- va_start(ap, s);
- vfprintf(stderr, s, ap);
- va_end(ap);
- fputc('\n', stderr);
- }
-
- #ifndef yywrap
- yywrap() {return 1;}
- #endif
-